package com.hoo.util;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import com.hoo.common.constant.Constant;

/**
 * IpUtil.java
 * 
 * @author liyuhang
 */
public abstract class IpUtils {

	private static final Pattern IP_PATTERN = Pattern
			.compile("([1-9]|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3}");

	private static Logger logger = Logger.getLogger(IpUtils.class);

	private static SimpleDateFormat sdf = new SimpleDateFormat();

	private static final Sequence sequence = Sequence.getSequence();

	/**
	 * 工具类无法实例化
	 */
	private IpUtils() {
		super();
	}

	public static String flowid() {
		sdf.applyPattern("yyMMddHHmmss");
		String timetip = sdf.format(new Date());
		return timetip + String.valueOf(sequence.getNextSeq());
	}

	/**
	 * 检验是否合法IP
	 * 
	 * @param ipAddress
	 * @return
	 */
	public static boolean isValidIp(String ipAddress) {
		return IP_PATTERN.matcher(ipAddress).matches();
	}

	/**
	 * 字符串ip转换为long
	 * 
	 * @param 字符串ip
	 * @return
	 */
	private static long getStringIpToLong(String ip) {
		String[] ips = ip.split("[.]");
		long num = 16777216L * Long.parseLong(ips[0]) + 65536L
				* Long.parseLong(ips[1]) + 256 * Long.parseLong(ips[2])
				+ Long.parseLong(ips[3]);
		return num;
	}

	/**
	 * 长整型ip转换为string
	 * 
	 * @param long型ip
	 * @return
	 */
	public static String getLongIpToString(long ipLong) {

		long[] mask = { 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 };
		long num = 0;
		StringBuffer ipInfo = new StringBuffer();
		for (int i = 0; i < 4; i++) {
			num = (ipLong & mask[i]) >> (i * 8);
			if (i > 0) {
				ipInfo.insert(0, ".");
			}
			ipInfo.insert(0, Long.toString(num, 10));
		}
		return ipInfo.toString();
	}

	/**
	 * 获取真实ip
	 * 
	 * @param request
	 * @return
	 */
	public static String getIpAddr(HttpServletRequest request) {
		if (request == null) {
			return "unknown";
		}
		String ip = request.getHeader("x-forwarded-for");
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("HTTP_CLIENT_IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("HTTP_X_FORWARDED_FOR");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getRemoteAddr();
		}
		// 多级反向代理
		if (null != ip && !"".equals(ip.trim())) {
			StringTokenizer st = new StringTokenizer(ip, ",");
			if (st.countTokens() > 1) {
				return st.nextToken();
			}
		}
		return ip;
	}

	public static String getLocationStr(final String ip) {
		Map<String, String> pcaMap = getLocationPCA(ip);
		return pcaMap.get(Constant.PROVINCE) + " " + pcaMap.get(Constant.CITY)
				+ " " + pcaMap.get(Constant.AREA);
	}

	public static Map getLocationPCA(final String ip) {
		Map pca = new HashMap();
		try {
			IPSeeker seeker = InitData.getIPSeeker();
			String ipStr = seeker.getCountry(ip);
			ipStr = StringUtils.isNotBlank(ipStr) ? ipStr.trim() : "";
			//
			String province = "";
			String city = "";
			String area = "";
			//
			if (ipStr.indexOf("省") == -1) {
				if (ipStr.indexOf("市") > -1) {
					String[] cArr = ipStr.split("市");
					city = cArr[0];
					area = ipStr.substring(cArr[0].length() + 1);
				}
			} else {
				String[] pArr = ipStr.split("省");
				province = pArr[0];
				//
				String cStr = ipStr.substring(pArr[0].length() + 1);
				if (cStr.indexOf("市") > -1) {
					String[] cArr = cStr.split("市");
					city = cArr[0];
					area = cStr.substring(cArr[0].length() + 1);
				}
			}

			pca.put(Constant.PROVINCE, StringUtils.isBlank(province) ? city
					: province);
			pca.put(Constant.CITY, city);
			pca.put(Constant.AREA, area);
		} catch (Exception e) {
			logger.error("ip 反向解析异常 : " + ip);
		}
		//
		return pca;
	}

	/* */

	public int IpStringToInt(String ipAddress) {
		byte[] addrBytes;
		int addr;
		addrBytes = ipAddress.getBytes();
		addr = ((addrBytes[3] & 0xff) << 24) | ((addrBytes[2] & 0xff) << 16)
				| ((addrBytes[1] & 0xff) << 8) | (addrBytes[0] & 0xff);
		return addr;
	}

	/**
	 * 将String类型IP地址转换为int类型
	 * 
	 * @param ip
	 * @return int
	 */
	public static int ipToInt(String ip) {
		String[] ips = ip.split("\\.");
		return (Integer.parseInt(ips[0]) << 24)
				+ (Integer.parseInt(ips[1]) << 16)
				+ (Integer.parseInt(ips[2]) << 8) + Integer.parseInt(ips[3]);
	}

	/**
	 * 将int类型IP地址转换为string类型
	 * 
	 * @param i
	 * @return String
	 */
	public static String intToIp(int i) {
		return ((i >> 24) & 0xFF) + "." + ((i >> 16) & 0xFF) + "."
				+ ((i >> 8) & 0xFF) + "." + (i & 0xFF);
	}

	public static void main(String[] arg) {
		// isFromChina("27.128.0.5", "D:\\cn_ip_seg.properties");
		// System.out.println(ipToInt("192.168.100.203"));

		// System.out.println(intToIp(-1062705973));

	}

}
